package algorithm;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Random;
import java.util.Set;

/**
 * @program: util
 * @description: 一张扑克牌，多加大王和小王，随机选5张，判断是否连续， J Q K 为 11，12，13
 * @author: zhouliangliang
 * @create: 2021-05-11 17:26
 **/
public class PlayCard {

    private int []card = new int[56];

    private void makeCard() {
        //初始化
        for(int i=1; i<=13; i++) {
            card[i-1] = i;
            card[i-1+13] = i;
            card[i-1+26] = i;
            card[i-1+39] = i;
        }

        //输出
        System.out.println("扑克牌");
        Arrays.stream(card).forEach(item->{
            System.out.print(item + ", ");
            if((item % 13) == 0 && item != 0) {
                System.out.println();
            }
        });
        System.out.println();
    }

    public void card() {

        //选牌,随机选5张
        int []array = new int[5];
        int times = 0;
        //选过的牌不能在选
        Set<Integer> set = new HashSet<>();
        while (times !=5) {
            Random random = new Random();
            int num = random.nextInt();
            int index = Math.abs(num) % 56;
            if(!set.contains(index)) {
                array[times++] = card[index];
            }
        }

        //排序
        Arrays.sort(array);
        //计算是否连续
        boolean flag = sequence(array);
        StringBuilder builder = new StringBuilder();
        for(int i=0; i<array.length; i++) {
            builder.append(array[i]).append(",");
        }

        if(flag){
            System.err.println("随机选出的5张 : " + builder.toString() + " 连续");
        } else {
            System.out.println("随机选出的5张 : " + builder.toString() + " 不连续");
        }
    }

    /**
     * 计算是否是连续的
     * 通过消耗0来计算是否是连续的
     * 通过计算最大值和最小值之间的差计算是否连续不靠谱，因为会出现重复数字的情况
     * @param array
     * @return
     */
    private boolean sequence(int []array) {

        //0的个数
        int zeroNum = 0;
        for (int i=0;i<array.length; i++) {
            if(array[i] == 0) {
                zeroNum ++;
                continue;
            }
            break;

        }
        //判断是不是连续
        for(int i=0; i < array.length; i++) {

            if(array[i] == 0) {
                continue;
            }

            if(zeroNum < 0 ) {
                return false;
            }

            //两张牌相等
            if((i+1)< array.length && array[i+1] - array[i] ==0) {
                return false;
            }

            //等于1的时候什么都不需要做，证明连续
            //大于1的时候需要消耗0
            if((i+1)< array.length && array[i+1] - array[i] >1) {
                zeroNum = zeroNum - (array[i+1] - array[i] -1);
            }
        }
        return true;
    }

    public static void main(String[] args) throws Exception{
        PlayCard pc = new PlayCard();
//        int array[] = new int[5];
//        array[0] = 0;
//        array[1] = 0;
//        array[2] = 1;
//        array[3] = 3;
//        array[4] = 7;
//        System.out.println(pc.sequence(array));

        pc.makeCard();
        for(int i=0; i< 2000; i++) {
//            Thread.sleep(300);
            pc.card();
        }
    }
}
